package com.kesh.ltank.game;

import java.io.IOException;
import java.io.InputStream;

import android.content.SharedPreferences;
import android.graphics.Point;

import com.android.framework.FileIO;
import com.android.framework.Input.TouchEvent;
import com.kesh.ltank.game.GlobalVars.Difficulty;
import com.kesh.ltank.game.GlobalVars.Direction;
import com.kesh.ltank.game.GlobalVars.PlayImages;
import com.kesh.ltank.game.GlobalVars.PlayObjects;

public class Utils {

	public static Difficulty getDifficulty(int inDcltyValue) {
		Difficulty outDclty = null;

		for (GlobalVars.Difficulty curDclty: GlobalVars.Difficulty.values()) {
			if(curDclty.dcltyValue==inDcltyValue){
				outDclty=curDclty;
			}
		}
		return outDclty;
	}

	public static PlayImages getPlayImage(int inFieldId) {

		for (GlobalVars.PlayImages curPlayImage : GlobalVars.PlayImages.values()) {
			if(curPlayImage.id==inFieldId)
				return curPlayImage;
		}
		
		return null;
	}

	public static PlayObjects getPlayObject(int inFieldId) {
		PlayObjects outPlayObject = null;

		for (GlobalVars.PlayObjects curPlayObject : GlobalVars.PlayObjects.values()) {
			if(curPlayObject.id==inFieldId)
				outPlayObject=curPlayObject;
		}
		return outPlayObject;
	}

	public static void loadLvlData(FileIO fio){
		try {
			InputStream fi = fio.readAsset(GlobalVars.lvlFileName);
			GlobalVars.lvlData = new byte[fi.available()];
			fi.read(GlobalVars.lvlData);
			fi.close();
		} catch (IOException e) {
			throw new RuntimeException("Error Reading Level Data File");
			// TODO - exception handling
		}
	}

	public static void saveLevelNumber(FileIO fi, int currentLevel) {
		SharedPreferences settings = fi.getSharedPref();
		SharedPreferences.Editor editor = settings.edit();
		editor.putInt("PlayedLevels", currentLevel);
		editor.commit();
		GlobalVars.currentLevel = currentLevel;
	}
	
	public static Point getCenterPixPos(Point inPos) {
		Point outPoint = new Point();
		outPoint.x = GlobalVars.playFieldStart.x + (inPos.x * GlobalVars.playImageScaledLen.x) + (GlobalVars.playImageScaledLen.x/2);
		outPoint.y = GlobalVars.playFieldStart.y + (inPos.y * GlobalVars.playImageScaledLen.y) + (GlobalVars.playImageScaledLen.y/2);
		return outPoint;
	}

	public static PlayObjects turnTank(Direction inDirection){
		PlayObjects outTank=PlayObjects.LTank_U;
		switch (inDirection) {
			case Up: outTank=PlayObjects.LTank_U;break;
			case Right: outTank=PlayObjects.LTank_R;break;
			case Down: outTank=PlayObjects.LTank_D;break;
			case Left: outTank=PlayObjects.LTank_L;break;
		}
		return outTank;
	}

	public static PlayObjects destroyTank(PlayObjects curTank){
		PlayObjects outTank=PlayObjects.ATank_U;
		switch (getDirection(curTank)) {
			case Up: outTank=PlayObjects.DTank_U;break;
			case Right: outTank=PlayObjects.DTank_R;break;
			case Down: outTank=PlayObjects.DTank_D;break;
			case Left: outTank=PlayObjects.DTank_L;break;
		}
		return outTank;
	}
	
	public static Direction getDirection(PlayObjects curObj){
		Direction outDirection = Direction.Up;
		String objName = curObj.name();
		if(objName.contains("_U")) outDirection=Direction.Up;
		if(objName.contains("_R")) outDirection=Direction.Right;
		if(objName.contains("_D")) outDirection=Direction.Down;
		if(objName.contains("_L")) outDirection=Direction.Left;
		return outDirection;
	}

	public static Point getNextPosition(Point curPos, Direction moveDirection){
		Point nxtPos = new Point();
		
		switch (moveDirection) {
			case Up: nxtPos.x=curPos.x;nxtPos.y=curPos.y-1;break;
			case Right: nxtPos.x=curPos.x+1;nxtPos.y=curPos.y;break;
			case Down: nxtPos.x=curPos.x;nxtPos.y=curPos.y+1;break;
			case Left: nxtPos.x=curPos.x-1;nxtPos.y=curPos.y;break;
		}
		
		return nxtPos;
	}
	
	public static boolean positionWithinBounds(Point curPoint){
		return (curPoint.x>=0 && curPoint.x<GlobalVars.lvlFieldLen.x && curPoint.y>=0 && curPoint.y<GlobalVars.lvlFieldLen.y);
	}

	public static boolean inBounds(TouchEvent event, int x, int y, int width, int height) {
		return event.x > x && event.x < x + width - 1 && event.y > y && event.y < y + height - 1;
	}

    @SuppressWarnings("rawtypes")
	public static Object resizeArray(Object oldArray, int newSize) {
        int oldSize = java.lang.reflect.Array.getLength(oldArray);
        Class elementType = oldArray.getClass().getComponentType();
        Object newArray = java.lang.reflect.Array.newInstance(elementType,newSize);
        int preserveLength = Math.min(oldSize,newSize);

        if (preserveLength > 0) {
           System.arraycopy(oldArray,0,newArray,0,preserveLength);
        }

        return newArray;
     }
}
